<html>
	<head>
		<title>Windows Azure How-to</title>
	</head>
	<body>
		<div id="Basic">
			<h2>Basic Setup and Configuration</h2>
			<ol>
				<li>Start Visual Studio 2010 as Administrator (Azure emulator requires elevated privileges)</li>
				<li>File->New->Project</li>
				<li>Under Visual C#->Web, choose ASP.NET MVC 3 Web Application</li>
				<li>Name your project something. I use the name 'HelloWorld' for the remainder of the How-to</li>
				<li>In 'New ASP.NET MVC 3 Project' dialog that pops up, select 'Empty' template. Choose Razor engine.</li>
				<li>Right click HelloWorld->Views in the Solution Explorer and add a folder named 'Home'</li>
				<li>In the Solution Explorer, right click the folder you just created and click to add a new 'View..' from the Add submenu</li>
				<li>In the dialog that pops up, name the page (i use 'index' for this how-to). This will generate 'index.cshtml'</li>
				<li>Right click Controllers in the Solution Explorer and click to add a new Controller.</li>
				<li>In the dialog name your new controller 'HomeController' and choose 'Empty controller' from the 'Template:' drop-down and click add</li>
				<li> Press 'F5' to do a test run.  A page should open in your default browser that says 'index'</li>
			</ol>
			<div>
				<p>At the root level of your project is a file name 'Global.asax.cs'. This file contains the entry point of your application.  This is where you can configure how to route URLs.  By default, URLs are routed to: /Controller/Action/id.  Where Controller is the name of a controller in your project (Home in our case) and Action is the name of a method within that controller.</p>
				<p>The controller we made came with a method by default named 'Index'.  This would correspond to an 'index.cshtml' file in the Home folder we created earlier. The application 'displays' the html when you 'return View()' from the Index method.  Similarly, if we added a method to the HomeController class that was identical to Index, but was instead named Index2, and we attempted to access /Home/Index2 there would be a 404 error since there is no Home/index2.cshtml.</p>
			</div>
		</div>
		<div id="GETPOST">
			<h2>GET and POST</h2>
			<ol>
				<li>Create two forms with a textbox and submit button in each in index.cshtml.  One uses GET the other POST (see example code).</li>
				<li>In your HomeController class, modify your 'Index' method to take a string parameter, where the parameter's name is whatever the id of your GET textbox is (name for this how-to). When the URL with the GET data in it is passed to your application the name of the value is mapped to the parameter of your Controller's action with the same name.  So it is required to make sure the names match up.</li>
				<li>Make a new method (named 'Post') that returns an ActionResult and has a string parameter (the same rules apply for naming the parameters with POST values as they do for GET).</li>
				<li>Right before Post's method declaration add the tag: <p><code>[AcceptVerbs(HttpVerbs.Post)]</code><p>. This tells the application that this method should only be called if there are POST values to pass to it.</li>
				<li>You can add the get/post data to the html through the ViewBag property.  Set ViewBag.Message to the get/post data.  Add in your html somewhere a reference to <p><code>@ViewBag.Message</code><p> (see sample code)</li>
			</ol>
		</div>
		<div id="AzureTables">
			<h2>Azure Tables Storage</h2>
			<p>Azure Tables is similar to Google Application Engine's Big Table that we went over in class.  Here are the basics of how to store and retrieve data (this how-to assumes you have done the previous how-tos).</p>
			<ol>
				<li>You may have to add a reference to System.Data.Services.Client, Microsoft.WindowsAzure, and Microsoft.WindowsAzure.StorageClient to your project (Right-click references in solution explorer and find them in the list and click 'Add').</li>
				<li>Right-click the Models folder and choose to Add a new class name TestDataModel.cs</li>
				<li>Add <p><code>using Microsoft.WindowsAzure.StorageClient</code><p> to the top of the file</li>
				<li>Change the TestDataModel class so it derives from TableServiceEntity class: <p><code>public class TestDataModel : TableServiceEntity{ </code><p></li>
				<li>Create a constructor that has two string parameters: partitionKey, and rowKey. Have the constructor pass these parameters to the base class. <p><code>public TestDataModel(string partitionKey, string rowKey) : base(partitionKey, rowKey){}</code><p> This class is the model of an entity that will be stored to the Table.</li>
				<p>The PartitionKey is used to determine which partition of the table to store this data.</p>
				<p>The RowKey is a unique identifier for an entity within a partition. Together with the PartitionKey a unique key for any entity is created.</p>
				<li>Create a default constructor (no parameters) to create random keys as well. <p><code>public TestDataModel(){}</code><p></li>
				<li>Add two public string properties called 'Data' and 'Method' both with get and set: <p><code>public string Data {get;set;}</code><p><p><code>public string Method {get;set;}</code><p></li>
				<li>Create a new class in the project root called TestDataServiceContext</li>
				<li>add <p><code>System.Data.Services.Client, Microsoft.WindowsAzure and Microsoft.WindowsAzure.StorageClient</code><p> namespaces to class</li>
				<li>make the TestDataServiceContext class inherit from TableServiceContext: <p><code>public class TestDataServiceContext : TableServiceContext {</code><p></li>
				<li>create constructor with 2 parameters and pass them to the base class: <p><code>public TestDataServiceContext(string baseAddress, StorageCredentials credentials) : base(baseAddress, credentials) {</code><p> </li>
				<li>create two properties in class: <p><code>public const string DataTableName = "DataTable";</code><p>, and <p><code>public IQueryable<TestDataModel> DataTable{ get{ return this.CreateQuery<TestDataModel>(DataTableName);}}</code><p> DataTable is the representaion of the actual storage table in your application.</li>
				<li>Add a new class called TestDataSource.cs</li>
				<li>Add using directives for <p><code>Microsoft.WindowsAzure, Microsoft.WindowsAzure.StorageClient, and System.Data.Services.Client</code><p> to the new file.</li>
				<li>Add <p><code>private TestDataServiceContext _ServiceContext = nulll;</code><p> to the class. This is the object that represents our connection to the storage server.</li>
				<li>Create a constructor, in the constructor we will setup the connection to Windows Azure Storage:
				<p><code>
				 public TestDataSource()
				{
					var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
					_ServiceContext = new TestDataServiceContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);
					storageAccount.CreateCloudTableClient().CreateTableIfNotExist(TestDataServiceContext.DataTableName);
				}</code><p>
				</li>
				<li>We need to add the configuration setting, DataConnectionString, that we reference in the constructor.  Right click the item in the 'Roles' folder in your Azure project and go to properties. (You must complete the add a Windows Azure Deployment project How-to before this step).</li>
				<li>In the properties window go to the settings tab.</li>
				<li>Add a new setting with Name 'DataConnectionString' of type 'Connection String' and Value 'UseDevelopmentStorage=true'</li>
				<li>Click the '...' button on the far right and make sure the 'Use the Windows Azure storage emulator' radio button is selected and press ok.</li>
				<li>Add the following methods to TestDataSource class:
						<p><code>
						public IEnumerable<TestDataModel> Select()
						{
							var results = from c in _ServiceContext.DataTable
										  select c;

							var query = results.AsTableServiceQuery<TestDataModel>();
							var queryResults = query.Execute();

							return queryResults;
						}
						</code><p>
						<p><code>
						public void Delete(TestDataModel item)
						{
							_ServiceContext.AttachTo(TestDataServiceContext.DataTableName, item);
							_ServiceContext.DeleteObject(item);
							_ServiceContext.SaveChanges();
						}
						</code><p>
						<p><code>
						public void Insert(TestDataModel item)
						{
							_ServiceContext.AddObject(TestDataServiceContext.DataTableName, item);
							_ServiceContext.SaveChanges();
						}
						</code><p>
				</li>
				<li>To use this you will have to edit the Application_Start method in Global.asax.cs. Add using directives for <p><code>Microsoft.WindowsAzure, Microsoft.WindowsAzure.ServiceRuntime</code><p></li>
				<li>Add this code at the end of the Application_Start method:
							<p><code>
							CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
							{
								configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

								RoleEnvironment.Changed += (sender, arg) =>
								{
									if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
										.Any((change) => (change.ConfigurationSettingName == configName)))
									{
										if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
										{
											RoleEnvironment.RequestRecycle();
										}
									}
								};
							});
							</code><p>
				</li>
				<li>You can use the select, Delete, and Insert functions to access and do operations on the Azure Table.  Use a Controller class to call these functions. (See sample code for an example)</li>
		</div>
		<div id="AzureDeployment">
			<h2>Add a Windows Azure Deployment Project</h2>
			<ol>			
				<li>Right click <Project-name> in the solution explorer and click 'Add Windows Azure Deployment Project' and new Azure Deployment project will be added to your solution</li>
				<li>Hit F5 to test locally. The Windows Azure emulator will start, this may take a few minutes (you must be running VS2010 as with elevated privileges for this to work!).</li>
				<p>Next, to deploy to the cloud:</p>
				<li>Right-click your project and select 'Publish to Windows Azure'</li>
				<li>Click the sign-in to download credentials link.  Save the file it prompts you to download and when it is download click the 'Import...' button and choose the file you just downloaded.</li>
				<li>Click next.<li>
				<li>In the 'Create Windows Azure Services' enter a name for your service and select a location. Click OK.</li>
				<li>click next and finish. Wait for it to complete then click the URL!</li>
				<p>If you followed this how-to you will be prompted to create a Storage Account as well as a Hosted service.</p>
			</ol>
		</div>
	</body>
</html>